/*
 * Created by SharpDevelop.
 * User: Guy Fomi
 * Date: 2/6/2011
 * Time: 2:14 PM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections;
using System.Collections.Generic;
using HtmlAgilityPack;
using System.Web.Script.Serialization;
using FileSystemDatabase;
using TomatoSynchronizer.Entities;
using Newtonsoft.Json;
using System.IO;
using Newtonsoft.Json.Linq;
using antiufo.HttpPost;
using System.Collections.Specialized;
using System.Net;

namespace TomatoSynchronizer.Store
{
	/// <summary>
	/// Description of SlideImageStore.
	/// </summary>
	public class SlideImageStore : IStore<SlideImage>
	{
		private Site _site;
		public Site site {
			get { return _site; }
			set { _site = value; }
		}
		
		private HtmlWeb _client;
		
		private JsonDatabase db;
		
		public void PersistItems(List<SlideImage> items)
		{
			db.Write<List<SlideImage>>(items,_site.Name);
		}
		
		public void Truncate()
		{
			SlideImage[] _images = LoadItems();
			
			foreach(SlideImage image in _images)
			{
				if(!DeleteItem(image.image_id))
				{
					throw new Exception("Could not delete the SlideImage " + image.description + " in site " + _site.Name);
				}
			}
			
			db.Truncate();
		}
		
		public void PersistItem(SlideImage item)
		{
			db.Write<SlideImage>(item,item.image_id);
		}
		
		public bool MoveItem(string itemId, string folderId)
		{
			throw new NotImplementedException();
		}
		
		public SlideImageStore(Site site,HtmlWeb client)
		{
			db = new JsonDatabase("sites/" + site.Name + "/SlideImages");
			_site = site;
			_client = client;
		}
		
		public bool DeleteItem(string itemId)
		{
			string url = _site.Url + "/admin/json.php?action=delete_slide_image&image_id=" + itemId + "&module=slide_images";
			HtmlDocument doc = _client.Load(url);

			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(node.InnerText);
			foreach (string key in json.Keys) {
				if (key == "success") {
					var response = bool.Parse(json[key].ToString());
					if (response) {
						db.Delete<SlideImage>(itemId);
					}

					return response;
				}
			}

			throw new Exception("Could not delete the SlideImage " + itemId + " in site " + _site.Name);
		}
		
		public SlideImage[] LoadItems()
		{
			SlideImage[] items = db.Read<SlideImage>();
			foreach(SlideImage item in items)
			{
				item.Store = this;
			}
			return items;
		}
		
		public SlideImage LoadItem(string itemId)
		{
			SlideImage item = db.Read<SlideImage>(itemId);
			if (item != null) {
				item.Store = this;
				return item;
			}

			return null;
		}
		
		public bool Contains(SlideImage item)
		{
			throw new NotImplementedException();
		}
		
		private List<SlideImage> images;
		public List<SlideImage> GetItems()
		{
			db.Truncate();
			images = new List<SlideImage>();
			
			string url = _site.Url + "/admin/json.php?action=list_slide_images&module=slide_images";
			HtmlDocument doc = _client.Load(url);
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			Dictionary<string,object> json = serialiser.Deserialize<Dictionary<string,object>>(node.InnerText);
			foreach (string key in json.Keys) {
				if (key == "records") {
					ArrayList recs = (ArrayList)json[key];
					for (int i = 0; i < recs.Count; i++) {
						Dictionary<string, object> record = (Dictionary<string, object>)recs[i];
						SlideImage image = GetItem(record["image_id"].ToString());
						images.Add(image);
						PersistItem(image);
					}
				}
			}
			
			PersistItems(images);
			
			return images;
		}

		public List<SlideImage> DownloadItems()
		{
			images = new List<SlideImage>();
			
			string url = _site.Url + "/admin/json.php?action=list_slide_images&module=slide_images";
			HtmlDocument doc = _client.Load(url);
			HtmlNode node = doc.DocumentNode.SelectSingleNode("/");
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			Dictionary<string,object> json = serialiser.Deserialize<Dictionary<string,object>>(node.InnerText);
			foreach (string key in json.Keys) {
				if (key == "records") {
					ArrayList recs = (ArrayList)json[key];
					for (int i = 0; i < recs.Count; i++) {
						Dictionary<string, object> record = (Dictionary<string, object>)recs[i];
						SlideImage image = GetItem(record["image_id"].ToString());
						images.Add(image);
					}
				}
			}
			
			return images;
		}
		
		public SlideImage GetItem(string itemId)
		{
			string url = _site.Url + "/admin/json.php?action=load_slide_images&image_id=" + itemId + "&module=slide_images";

			WebClient client = new WebClient();
			string data = client.DownloadString(url);
			Dictionary<string, string> _slide_images = new Dictionary<string, string>();

			try {
				JavaScriptSerializer serialiser = new JavaScriptSerializer();
				Dictionary<string,object> json1 = serialiser.Deserialize<Dictionary<string,object>>(data);
				foreach(string key in json1.Keys)
				{
					if(key == "data")
					{
						Dictionary<string,object> slide_image = (Dictionary<string,object>)json1[key];
						foreach(string cle in slide_image.Keys)
						{
							if(cle.StartsWith("slide_image"))
							{
								string img = slide_image[cle].ToString().Substring(slide_image[cle].ToString().IndexOf("/"));
								img = img.Substring(img.IndexOf("/") + 1);
								img = img.Substring(img.IndexOf("/") + 1);
								img = img.Split('\\')[0];
								img = img.Split(new string[]{"width"},StringSplitOptions.None)[0];
								img = img.TrimEnd();
								img = img.Substring(0,img.Length -1);
								_slide_images[cle] = img;
							}							
						}
					}
				}
				
				JObject json = (JObject)JsonConvert.DeserializeObject(data);
				foreach (JProperty property in json.Properties()) {
					if (property.Name == "data") {
						var val = property.Value.ToString();
						SlideImage image = new SlideImage(val);
						image.slide_images = _slide_images;
						foreach(string key in image.slide_images.Keys)
						{
							if(!string.IsNullOrEmpty(image.slide_images[key]))
							{
								string image_name = image.slide_images[key];
								Utility.DownloadImage(_site.Url + "/images/" + image_name,"sites/" + _site.Name + "/SlideImages/" + itemId + "/");
							}
						}
						
						image.Store = this;
						return image;
					}
				}

				throw new Exception("Could not load the SlideImage " + itemId);
			} catch (JsonReaderException ex) {
				throw ex;
			}
		}
		
		public bool UpdateItem(SlideImage item)
		{
			var post = new antiufo.HttpPost.HttpPostRequest(_site.Url + "/admin/json.php");

			post.AddField("status",item.status);
			post.AddField("sort_order",item.sort_order);
			post.AddField("module", "slide_images");
			post.AddField("action", "save_slide_images");
			post.AddField("image_id",item.image_id);
			
			foreach(string key in item.slide_images.Keys)
			{
				post.AddFile(key,item.slide_images[key]);
			}
			
			foreach(string key in item.descriptions.Keys)
			{
				post.AddField(key,item.descriptions[key]);
			}

			foreach(string key in item.image_urls.Keys)
			{
				post.AddField(key,item.image_urls[key]);
			}
			
			var resp = post.PostData();

			Stream s = resp.GetResponseStream();
			StreamReader sr = new StreamReader(s);

			var response = sr.ReadToEnd();
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			IDictionary json = serialiser.Deserialize<IDictionary>(response);
			if (json != null) {
				foreach (string key in json.Keys) {
					if (key == "success") {
						return bool.Parse(json[key].ToString());
					}
				}
			}

			throw new Exception("Could not update the SlideImage " + item.image_id + " in site " + _site.Name);
		}
		
		public string InsertItem(SlideImage item)
		{
			var post = new antiufo.HttpPost.HttpPostRequest(_site.Url + "/admin/json.php");

			post.AddField("status",item.status);
			post.AddField("sort_order",item.sort_order);
			post.AddField("module", "slide_images");
			post.AddField("action", "save_slide_images");
			
			foreach(string key in item.slide_images.Keys)
			{
				post.AddFile(key,item.slide_images[key]);
			}
			
			foreach(string key in item.descriptions.Keys)
			{
				post.AddField(key,item.descriptions[key]);
			}

			foreach(string key in item.image_urls.Keys)
			{
				post.AddField(key,item.image_urls[key]);
			}
			
			var resp = post.PostData();

			Stream s = resp.GetResponseStream();
			StreamReader sr = new StreamReader(s);

			var response = sr.ReadToEnd();
			
			JavaScriptSerializer serialiser = new JavaScriptSerializer();
			
			try
			{
				IDictionary json = serialiser.Deserialize<IDictionary>(response);
				if (json != null) {
					foreach (string key in json.Keys) {
						if (key == "success") {
							if (bool.Parse(json[key].ToString())) {
								
								var _images = DownloadItems();
								
								foreach(SlideImage image in _images)
								{
									var _image = LoadItem(image.image_id);
									
									if(_image == null)
									{
										PersistItem(image);
										return image.image_id;
									}
								}
							}
						}
					}
				}
			}
			catch(ArgumentException)
			{
				throw new Exception(response);
			}

			throw new Exception("Could not insert the SlideImage " + item.image_id + " in site " + _site.Name);
		}
	}
}
